package edu.westga.datastructures.sets;

/**
 * 
 * @author CS3152
 * @version Spring 2013
 *
 * Set - an unordered collection that does not allow pairs of 
 * elements el1 and el2 with el1.equals(el2) and does not allow
 * null elements.
 * 
 * The Set interface provides an iterator. The iterator does not
 * guarantee any order of the traversed elements.
 */
public interface Set<E> extends Iterable<E>{
	/**
	 * returns the number of elements in this set.
	 * 
	 * @return the number of elements in this set
	 */
	int size ();
	
	/**
	 * returns true if this set contains no elements
	 * 
	 * @return true iff this set contains no elements
	 */
	boolean isEmpty ();
	
	/**
	 * returns true if this set is equal to the specified set
	 * 
	 * @requires: aSet != null  
	 * 
	 * @param aSet - set that is checked for equality
	 * 
	 * @returns true iff each element in this set is contained in the
	 *          specified set and vice versa
	 * 
	 * @throws NullPointerException - if the specified set is null
	 */
	boolean equals (Set<E> aSet);
	
	/**
	 * returns true if this set is a proper subset of the specified
	 * set
	 * 
	 * @requires: aSet != null  
	 * 
	 * @param aSet - set that is checked to contain this set
	 * 
	 * @returns true iff each element in this set is contained in the
	 *          specified set and !this.equals(aSet)
	 * 
	 * @throws NullPointerException - if the specified set is null
	 */
	boolean isSubsetOf (Set<E> aSet);
		
	/**
	 * returns true if this set and the specified set are disjoint. 
	 * More specific, returns true if there is no element el1 in this 
	 * set and el2 in the specified set aSet with el1.equals(el2).
	 * 
	 * @param aSet - set that is check to be disjoint with this set
	 * 
	 * @return true iff this set and the specified set are disjoint
	 * 
	 * @throws NullPointerException - if the specified set is null
	 */
	boolean isDisjoint (Set<E> aSet);
	
	/**
	 * returns true if this set contains an element el1 with el.equals(el1).
	 * 
	 * @requires: el != null
	 * 
	 * @param el - element whose presence is tested
	 * 
	 * @return true iff this set contains the specified element
	 * 
	 * @throws NullPointerException - if the specified element is null
	 */
	boolean contains (E el);
	
	/**
	 * adds the specified element to this set
	 * 
	 * @requires: el != null AND !this.contains(el) 
	 * 
	 * @param el - element to be inserted
	 * 
	 * @return true 
	 * 
	 * @throws NullPointerException - if the specified element is null
	 * 		   IllegalArgumentException - if this set contains the specified element
	 */
	boolean add (E el);

	/**
	 * removes the specified element from this set. If the specified element is not
	 * contained in this set, the set remains unchanged.
	 * 
	 * @requires: el != null
	 * 
	 * @param el - element to be removed
	 * 
	 * @return true iff this set contained the specified element
	 * 
	 * @throws NullPointerException - if the specified element is null
	 */
	boolean remove (E el);
	

	/**
	 * returns the union of this set and the specified set
	 * 
	 * @requires: aSet != null  
	 * 
	 * @param aSet - operand of the union operation
	 * 
	 * @returns a set that contains exactly the elements of this set and 
	 *          the specified set aSet 
	 * 
	 * @throws NullPointerException - if the specified set is null
	 */
	Set<E> union (Set<E> aSet);

	/**
	 * returns the intersection of this set and the specified set
	 * 
	 * @requires: aSet != null  
	 * 
	 * @param aSet - operand of the intersection operation
	 * 
	 * @returns a set that contains exactly the elements that are  
	 *          contained this set and the specified set aSet 
	 * 
	 * @throws NullPointerException - if the specified set is null
	 */
	Set<E> intersection (Set<E> aSet);

	/**
	 * returns the difference of this set in respect to the 
	 * specified set
	 * 
	 * @requires: aSet != null  
	 * 
	 * @param aSet - operand of the difference operation
	 * 
	 * @returns a set that contains exactly the elements of this set  
	 *          that are not contained in the specified set aSet 
	 * 
	 * @throws NullPointerException - if the specified set is null
	 */
	Set<E> difference (Set<E> aSet);
}
